/*
 * @Author: firefly717
 * @Date: 2024-06-22 11:11:34
 * @LastEditTime: 2024-06-22 19:49:10
 * @Description: Person模型类
 */

import 'dart:convert';

enum Sex { none, male, female }

class Person {
  /// 默认构造函数，构造函数不允许放在扩展中
  Person(this.name, int age, {this.nickName, this.sex = Sex.male}) : _age = age;

  /// 命名构造函数
  Person.custom(this.name, int age, {this.sex = Sex.male}) : _age = age {
    this.nickName = "没想好";
  }

  /// 工厂构造函数
  factory Person.template(String name, int age) {
    if (_cache.containsKey(name)) {
      return _cache[name]!;
    } else {
      final p = Person.custom(name, age);
      _cache[name] = p;
      return p;
    }
  }

  final String name;
  final Sex sex;
  // 私有属性
  int _age;
  // 可选参数
  String? nickName;

  // Dart的静态属性和静态方法：https://www.jianshu.com/p/7f71b6a4e8ae
  static Map<String, Person> _cache = {};

  // MARK:Data Parse
  factory Person.fromRawJson(String str) => Person.fromJson(json.decode(str));

  String toRawJson() => json.encode(toJson());

  factory Person.fromJson(Map<String, dynamic> json) => Person(
        json["name"],
        json["age"],
        nickName: json["nickName"],
      );

  Map<String, dynamic> toJson() => {
        "name": name,
        "age": age,
        "nickName": nickName,
        "sex": sex.value,
      };

  // MARK: system
  bool operator ==(dynamic otherObj) {
    if ((otherObj is Person) &&
        otherObj.name == name &&
        otherObj._age == _age &&
        otherObj.nickName == nickName) {
      return true;
    }
    return false;
  }

  @override
  String toString() {
    var msg;
    if (nickName != null && nickName!.isNotEmpty) {
      msg = "姓名：$name, 性别:${sex.title}, 别名: $nickName, hashCode=$hashCode \n";
    } else {
      msg = "姓名：$name, 性别:${sex.title}, hashCode=$hashCode \n";
    }
    return msg;
  }

  // 私有方法
  _secret() {
    print("年龄保密(#^.^#)");
  }
}

extension PersonExt on Person {
  /// 末尾增加逗号进行排版
  Person copyWith({
    String? name,
    int? age,
    String? nickName,
    Sex? sex,
  }) {
    return Person(
      name ?? this.name,
      age ?? this._age,
      nickName: nickName ?? this.nickName,
      sex: sex ?? this.sex,
    );
  }

  bool isOld() {
    return _age > 30 ? true : false;
  }

  // 计算属性
  int? get age {
    if (sex == Sex.male) {
      print("年龄: $_age");
      return _age;
    } else {
      if (_age > 30) {
        _secret();
        return null;
      } else {
        return _age;
      }
    }
  }
}

extension SexExt on Sex {
  // 计算属性
  String get title {
    switch (this) {
      case Sex.male:
        return "男";
      case Sex.female:
        return "女";
      default:
        return "未知";
    }
  }

  int get value {
    switch (this) {
      case Sex.male:
        return 1;
      case Sex.female:
        return 2;
      default:
        return 0;
    }
  }
}
